package com.quantum.reflection
{
	import com.quantum.util.StringUtils;

	/**
	 * Represents the member level (properties and methods) reflection info.
	 */
	public class AccessibleObject
	{
		/**
		 * The member name.
		 */
		public var name:String;

		/**
		 * The declaring type name.
		 * eg: com.quantum.reflection::ClassObjectTest
		 */
		public var declaringTypeName:String;

		/**
		 * The member's meta tags.
		 */
		public var metadataObjects:Vector.<MetadataObject>;

		/**
		 * Returns the tags objects corresponding to the given tag name.
		 */
		public function getMetadataObjects(metadataObjectName:String):Vector.<MetadataObject>
		{
			var result:Vector.<MetadataObject>=new Vector.<MetadataObject>();
			for each (var metadataObject:MetadataObject in this.metadataObjects)
			{
				if (metadataObject.name == metadataObjectName)
				{
					result.push(metadataObject);
				}
			}
			return result;
		}

		/**
		 * Checks whether any of this member's tags has the given name.
		 */
		public function hasMetadataObject(metadataObjectName:String):Boolean
		{
			for each (var metadataObject:MetadataObject in this.metadataObjects)
			{
				if (metadataObject.name == metadataObjectName)
				{
					return true;
				}
			}
			return false;
		}

		/**
		 * Returns the arguments of the tag having the given name.
		 */
		public function getMetadataArguments(metadataObjectName:String):Vector.<MetadataArgument>
		{
			var metadataArguments:Vector.<MetadataArgument>=new Vector.<MetadataArgument>();
			for each (var metadataObject:MetadataObject in this.metadataObjects)
			{
				if (metadataObject.metadataArguments != null && metadataObject.name == metadataObjectName)
				{
					metadataArguments.push(metadataObject.metadataArguments);
				}
			}
			return metadataArguments;
		}

		
		
		public function getMetadataArgumentValue(metadataObjectName:String, metadataArgumentKey:String=null):String
		{
			var values:Vector.<String> = getMetadataArgumentValues(metadataObjectName, metadataArgumentKey);
			if(values.length>0) {
				return values[0];
			}
			return null;
		}
		/**
		 * Returns the argument values of the tags having the given name.
		 * If a key is specified, then only arguments with the given key are considered.
		 */
		public function getMetadataArgumentValues(metadataObjectName:String, metadataArgumentKey:String=null):Vector.<String>
		{
			var values:Vector.<String>=new Vector.<String>();
			var metadataArguments:Vector.<MetadataArgument>=getMetadataArguments(metadataObjectName);
			for each (var metadataArgument:MetadataArgument in metadataArguments)
			{
				if (metadataArgumentKey == null || StringUtils.isEmpty(metadataArgument.key) || metadataArgumentKey == metadataArgument.key)
				{
					values.push(metadataArgument.value);
				}
			}
			return values;
		}

	/**
	 * @see ProfilingManager.getObjectSize.
	 */
//      public function getNestedSize():int {
//         var size1:int = ProfilingManager.instance.getObjectSize(this.name);
//         //declaringTypeName is (mostly) shared in ReflectionManager.
//         var size2:int = ProfilingManager.instance.getObjectSize(this.metadataObjects);
//         return  size1 + size2;
//      }
	}
}